home *** CD-ROM | disk | FTP | other *** search
-
- /***************************************************************************
-
- V_M_HDWR.INC
-
- include file for V_M_6502.C
-
- This file contains the hardware emulation routines.
-
- November 12, 1986 0:00
-
- ***************************************************************************/
-
- /* the following declarations are here because they are also used by the
- hardware service routines as well as by V_M_OPS.INC
- */
-
- /* status bits of the P register: (6502) NV_BDIZC */
-
- #define NBIT 0x80
- #define VBIT 0x40
- #define BBIT 0x10
- #define DBIT 0x08
- #define IBIT 0x04
- #define ZBIT 0x02
- #define CBIT 0x01
-
- /* status bits of the CCR register: (68000) BDIXNZVC */
-
- #define BITN 0x08
- #define BITV 0x02
- #define BITB 0x80
- #define BITD 0x40
- #define BITI 0x20
- #define BITZ 0x04
- #define BITC 0x01
- #define BITX 0x10
-
- #define DBUS D0
- #define IR D0
- #define REGA D1
- #define REGX D2
- #define REGY D3
- #define REGSP D4
- #define REGPC D5
- #define REGST D6
- #define REGEA D7
-
-
- #define REGEMUL A0 /* constant pointer to emul: */
- #define REGMEA A1 /* pointer to mem[ea] */
- #define REGMPC A2 /* pointer to mem[pc] */
- #define REGSTAT A3 /* pointer to stat[0] */
- #define GLOBAL A4
- #define REGOPS A5 /* constant pointer to vector table */
- #define LOCAL A6
- #define SP A7
-
- #define GRAPHICS 1
- #define TEXT 2
- #define FULLGRAF 4
- #define SPLITSCR 8
- #define PAGE1 16
- #define PAGE2 32
- #define LORES 64
- #define HIRES 128
-
- #define SETREAD ADDQ.W #1,isread(A4)
- #define SETWRITE CLR.W isread(A4)
- #define TESTWRITE TST.W isread(A4)
-
- #define SAVEREGS MOVEM.L D1-D7/A0-A3/A5,-(SP)
- #define LOADREGS MOVEM.L (SP)+,D1-D7/A0-A3/A5
-
- extern
- emul_serv(),
- nul() , w0400(), w0800(), w2000(), w4000(), sC000(), sC010(), sC030(),
- sC050(), sC051(), sC052(), sC053(), sC054(), sC055(), sC056(), sC057()
- ;
-
- int (*serv_hrdw[256])() = { /* array of pointers to 256 service routines */
-
- nul , w0400, w0800, w2000, w4000, nul , nul , nul , /* 128 write */
- nul , nul , nul , nul , nul , nul , nul , nul , /* no read */
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul , /* no read */
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- sC000, sC010, sC030, sC050, sC051, sC052, sC053, sC054, /* 128 read */
- sC055, sC056, sC057, nul , nul , nul , nul , nul , /* and write */
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul ,
- nul , nul , nul , nul , nul , nul , nul , nul
- } ;
-
- /* The following are variables required for the service routines */
-
- int videomode, /* state of video chip */
- isread , /* nonzero = read, zero = write */
- tempsound ;
- char keyboard, /* value of keyboard register */
- scrch ; /* character to plot */
- char *font, /* pointer to 8x8 system font */
- *exitptr ; /* pointer to exit_emul */
-
- int baddr1[25] = {
- 0, 1280, 2560, 3840, 5120, 6400, 7680, 8960,
- 10240, 11520, 12800, 14080, 15360, 16640, 17920, 19200, 20480,
- 21760, 23040, 24320, 25600, 26880, 28160, 29440, 30720
- } ;
-
- int baddr2[25] = {
- 0, 640, 1280, 1920, 2560, 3200, 3840, 4480, 5120, 5760, 6400, 7040,
- 7680, 8320, 8960, 9600, 10240, 10880, 11520, 12160, 12800, 13440, 14080,
- 14720, 15360
- } ;
-
-
- /* initialize the stat[] array and set defaults for power on */
- InitMachine() {
-
- for (ea=0; ea; *(mem+ea++)=0) ; /* clear out main memory */
- for (ea=0; ea; stat[ea++]=0) ; /* clear out stat array */
-
- for (ea=1024; ea<2048; ea++)
- if ( (ea&0x7F) < 120) stat[ea]=1 ; /* text page 1 */
-
- for (ea=2048; ea<3072; ea++)
- if ( (ea&0x7F) < 120) stat[ea]=2 ; /* text page 2 */
-
- for (ea=8192; ea<16384; ea++)
- if ( (ea&0x7F) < 120) stat[ea]=3 ; /* hires page 1 */
-
- for (ea=16384; ea<24576; ea++)
- if ( (ea&0x7F) < 120) stat[ea]=4 ; /* hires page 2 */
-
- stat[0xC000] = 128 ; /* keyboard register */
- stat[0xC010] = 129 ; /* keyboard strobe */
-
- stat[0xC030] = 130 ; /* speaker */
-
- stat[0xC050] = 131 ; /* graphics switch */
- stat[0xC051] = 132 ; /* text switch */
- stat[0xC052] = 133 ; /* full screen switch */
- stat[0xC053] = 134 ; /* split screen switch */
- stat[0xC054] = 135 ; /* page 1 switch */
- stat[0xC055] = 136 ; /* page 2 switch */
- stat[0xC056] = 137 ; /* lo-res switch */
- stat[0xC057] = 138 ; /* hi-res switch */
-
- videomode = TEXT|PAGE1|HIRES|FULLGRAF ; /* initial power on text mode */
-
- InitPrint(mode) ;
-
- } /* END OF INIT */
-
-
- dummy() { /* This function is never called.
- It's purpose is to allow the 68000 routines to pop into
- C once in a while.
- Therefore they must be inside a C function. */
-
-
- /* emul_serv is called whenever a read/write access is attempted
- to non-RAM memory locations, such as ROM or hardware registers.
-
- i.e. the status byte was non-zero.
-
- when status bytes are >=$80 (write-only)
- REGEA points to memory to read with D0
- this routine ends with JMP (REGEMUL) when writing
- and RTS when reading
-
- when status bytes are <> 0 (read and write)
- REGEA points to memory to write with D0
- byte to poke is in high byte of DBUS
- this routine ends with JMP (REGEMUL)
- */
- asm {
-
- emul_serv:
- ANDI.W #0x00FF,IR /* clear out bits 8..15 */
- ADD.W IR,IR
- ADD.W IR,IR /* calculate offset */
- LEA serv_hrdw(GLOBAL),REGMEA /* get start of vector table */
- MOVE.L 0(REGMEA,IR.W),REGMEA /* calculate correct vector */
- JMP (REGMEA) /* jump through it */
-
-
- nul: /* should never execute! but just in case */
- JMP (REGEMUL)
-
-
- w0400: /* handler for text page 1 */
- SWAP DBUS /* get character */
- MOVE.L REGEA,REGMEA
- MOVE.B DBUS,(REGMEA) /* do the actual write to memory */
- MOVE.B DBUS,scrch(GLOBAL) /* and to global variable */
-
- MOVE.W REGEA,ea(GLOBAL) /* let C know where to write */
- SAVEREGS /* save 6502 enviornment */
- } /* hop into C */
- if (videomode&PAGE1) { /* if page one selected, plot text */
- if (!TextPlot(scrch,ea)) LoPlot(scrch,ea) ;
- }
- asm { /* hop out of C, whee! */
- LOADREGS /* restore 6502 enviornment */
- JMP (REGEMUL) /* write-only routines go straight to emul */
-
- w0800: /* handler for text page 2 - similar to above */
- SWAP DBUS
- MOVE.L REGEA,REGMEA
- MOVE.B DBUS,(REGMEA)
- MOVE.B DBUS,scrch(GLOBAL)
-
- MOVE.W REGEA,ea(GLOBAL)
- SAVEREGS
- }
- if (videomode&PAGE2) TextPlot(scrch,ea) ;
- asm {
- LOADREGS
- JMP (REGEMUL) /* write-only routines go straight to emul */
-
- w2000: /* handler for hires page 1 */
- SWAP DBUS /* get byte */
- MOVE.L REGEA,REGMEA
- MOVE.B DBUS,(REGMEA) /* do the actual write to memory */
- MOVE.B DBUS,scrch(GLOBAL) /* and to global variable */
- MOVE.W REGEA,ea(GLOBAL) /* let C know where to write */
- SAVEREGS /* save 6502 enviornment */
- } /* hop into C */
- if (videomode&PAGE1) /* if corrrect display is on */
- HiPlot (scrch,ea) ; /* plot the byte */
- asm { /* hop out of C, whee! */
- LOADREGS /* restore 6502 enviornment */
- JMP (REGEMUL) /* write-only routines go straight to emul */
-
-
- w4000: /* handler for hires page 2 - similar to above */
- SWAP DBUS
- MOVE.L REGEA,REGMEA
- MOVE.B DBUS,(REGMEA)
- MOVE.B DBUS,scrch(GLOBAL)
- MOVE.W REGEA,ea(GLOBAL)
- SAVEREGS
- }
- if (videomode&PAGE2)
- HiPlot (scrch,ea) ;
- asm {
- LOADREGS
- JMP (REGEMUL)
-
- sC000:
- TESTWRITE
- BEQ C000write
- SAVEREGS
- }
- if (Bconstat(2) != 0) {
- *(mem+0xC000) = keyboard = Bconin(2)|0x80 ;
- }
- asm {
- LOADREGS
- RTS
- C000write: /* can't write to keyboard */
- JMP (REGEMUL)
-
- sC010:
- ANDI.B #0x7F,keyboard(GLOBAL) /* turn off high bit of keyboard */
- MOVE.L mem(GLOBAL),REGMEA
- ADDA.L #0xC000L,REGMEA
- MOVE.B keyboard(GLOBAL),(REGMEA) /* write it to memory */
- TESTWRITE
- BEQ C010write
- RTS
- C010write:
- JMP (REGEMUL)
-
- sC030:
- SAVEREGS
- }
- tempsound = Giaccess(0,7) ;
- Giaccess(55,128+7) ;
- Giaccess(5,128+6) ;
- Giaccess(16,128+8) ;
- Giaccess(1,128+11) ;
- Giaccess(0,128+12) ;
- Giaccess(0,128+13) ;
- Giaccess(63,128+7) ;
- Giaccess(tempsound,128+7) ;
- asm {
- LOADREGS
- TESTWRITE
- BEQ C030write
- RTS
- C030write:
- JMP (REGEMUL)
-
- sC050:
- ANDI.W #~TEXT,videomode(GLOBAL)
- ORI.W #GRAPHICS,videomode(GLOBAL)
- TESTWRITE
- BEQ C050write
- RTS
- C050write:
- JMP (REGEMUL)
-
- sC051:
- ANDI.W #~GRAPHICS,videomode(GLOBAL)
- ORI.W #TEXT,videomode(GLOBAL)
- TESTWRITE
- BEQ C051write
- RTS
- C051write:
- JMP (REGEMUL)
-
- sC052:
- ANDI.W #~SPLITSCR,videomode(GLOBAL)
- ORI.W #FULLGRAF,videomode(GLOBAL)
- TESTWRITE
- BEQ C052write
- RTS
- C052write:
- JMP (REGEMUL)
-
- sC053:
- ANDI.W #~FULLGRAF,videomode(GLOBAL)
- ORI.W #SPLITSCR,videomode(GLOBAL)
- TESTWRITE
- BEQ C053write
- RTS
- C053write:
- JMP (REGEMUL)
-
- sC054:
- ANDI.W #~PAGE2,videomode(GLOBAL)
- ORI.W #PAGE1,videomode(GLOBAL)
- TESTWRITE
- BEQ C054write
- RTS
- C054write:
- JMP (REGEMUL)
-
- sC055:
- ANDI.W #~PAGE1,videomode(GLOBAL)
- ORI.W #PAGE2,videomode(GLOBAL)
- TESTWRITE
- BEQ C055write
- RTS
- C055write:
- JMP (REGEMUL)
-
- sC056:
- ANDI.W #~HIRES,videomode(GLOBAL)
- ORI.W #LORES,videomode(GLOBAL)
- SAVEREGS
- }
- colors16() ; /* set 16 color palette */
- asm {
- LOADREGS
-
- TESTWRITE
- BEQ C056write
- RTS
- C056write:
- JMP (REGEMUL)
-
- sC057:
- ANDI.W #~LORES,videomode(GLOBAL)
- ORI.W #HIRES,videomode(GLOBAL)
- SAVEREGS
- }
- colors8() ; /* set 6 color palette */
- asm {
- LOADREGS
- TESTWRITE
- BEQ C057write
- RTS
- C057write:
- JMP (REGEMUL)
-
- }
- }
-
- /* text plotting routines to bypass GEM */
-
- InitPrint () {
-
- long fontptr[4] ;
- long *fonts ;
- int *header ;
- int x ;
-
- asm {
- DC.W 0xA000
- MOVE.L A1,fonts(A6)
- }
-
- for (x=0; x<3; x++) fontptr[x] = *fonts++ ;
- header = (int*) fontptr[1] ; /* header for 8x8 system font */
- font = (char *) (header[38]*65536L+header[39]) ;
- }
-
- TextPlot (text,loc)
- int text ;
- register int loc ;
- {
-
- register int smask, scrx, scry ;
- register char *newscr = scr_emul , *newfont = font ;
-
- if ((videomode&TEXT)||(videomode&SPLITSCR)) /* if we are in text mode */
- {
- loc &= 1023 ; /* convert to relative offset from start of screen */
- scry = (((loc&0x7F)/40)<<3) + (loc>>7) ; /* screen row */
- scrx = (loc&0x7F)%40 ; /* screen column */
-
- newfont += ((text&0x80) ? text : (text^0x20)+0xA0 ) & 0x7F ;
-
- if (!((videomode&SPLITSCR)&&(scry<20)&&!(videomode&TEXT))) {
-
- switch (mode) {
-
- case 0 :
- newscr += baddr1[scry] + (scrx&1) + ((scrx&~1)<<2) ;
- smask = (text&0x80) ? 0 : ~0 ;
- newscr[000] = newscr[002] = newscr[004] =
- newscr[006] = newfont[0]^smask ;
- newscr[160] = newscr[162] = newscr[164] =
- newscr[166] = newfont[256]^smask ;
- newscr[320] = newscr[322] = newscr[324] =
- newscr[326] = newfont[512]^smask ;
- newscr[480] = newscr[482] = newscr[484] =
- newscr[486] = newfont[768]^smask ;
- newscr[640] = newscr[642] = newscr[644] =
- newscr[646] = newfont[1024]^smask ;
- newscr[800] = newscr[802] = newscr[804] =
- newscr[806] = newfont[1280]^smask ;
- newscr[960] = newscr[962] = newscr[964] =
- newscr[966] = newfont[1536]^smask ;
- newscr[1120] = newscr[1122] = newscr[1124] =
- newscr[1126] = newfont[1792]^smask ;
- break ;
-
- case 1 :
- newscr += baddr1[scry] + (scrx&1) + ((scrx&~1)<<1) + 40;
- smask = (text&0x80) ? ~0 : 0 ;
- newscr[000] = ( newscr[002] = newfont[000]^smask ) ;
- newscr[160] = ( newscr[162] = newfont[256]^smask ) ;
- newscr[320] = ( newscr[322] = newfont[512]^smask ) ;
- newscr[480] = ( newscr[482] = newfont[768]^smask ) ;
- newscr[640] = ( newscr[642] = newfont[1024]^smask) ;
- newscr[800] = ( newscr[802] = newfont[1280]^smask) ;
- newscr[960] = ( newscr[962] = newfont[1536]^smask) ;
- newscr[1120]= ( newscr[1122]= newfont[1792]^smask) ;
- break ;
-
- case 2 :
- newscr += baddr2[scry] + scrx + 1220 ;
- smask = (text&0x80) ? ~0 : 0 ;
- newscr[0] = newfont[0]^smask ;
- newscr[80] = newfont[256]^smask ;
- newscr[160] = newfont[512]^smask ;
- newscr[240] = newfont[768]^smask ;
- newscr[320] = newfont[1024]^smask ;
- newscr[400] = newfont[1280]^smask ;
- newscr[480] = newfont[1536]^smask ;
- newscr[560] = newfont[1792]^smask ;
- }
- return(1) ;
- }
- }
- return(0) ; /* unsuccesful plot */
- }
-
- LoPlot (text,loc)
- register int text, loc ;
- {
-
- register int scrx, scry, temp ;
- register char *newscr = scr_emul ;
-
- loc &= 1023 ; /* convert to relative offset from start of screen */
- scry = (((loc&0x7F)/40)<<3) + (loc>>7) ; /* screen row */
- scrx = (loc&0x7F)%40 ; /* screen column */
-
- if (videomode&LORES)
- switch (mode) {
-
- case 0 :
- newscr += baddr1[scry] + (scrx&1) + ((scrx&~1)<<2) ;
- newscr[000] = newscr[160] = newscr[320] =
- newscr[480] = (text&1) ? ~0 : 0 ;
- newscr[002] = newscr[162] = newscr[322] =
- newscr[482] = (text&2) ? ~0 : 0 ;
- newscr[004] = newscr[164] = newscr[324] =
- newscr[484] = (text&4) ? ~0 : 0 ;
- newscr[006] = newscr[166] = newscr[326] =
- newscr[486] = (text&8) ? ~0 : 0 ;
- newscr[640] = newscr[800] = newscr[960] =
- newscr[1120] = (text&16) ? ~0 : 0 ;
- newscr[642] = newscr[802] = newscr[962] =
- newscr[1122] = (text&32) ? ~0 : 0 ;
- newscr[644] = newscr[804] = newscr[964] =
- newscr[1124] = (text&64) ? ~0 : 0 ;
- newscr[646] = newscr[806] = newscr[966] =
- newscr[1126] = (text&128) ? ~0 : 0 ;
- break ;
-
- case 1 :
- newscr += baddr1[scry] + (scrx&1) + ((scrx&~1)<<1) + 40;
- newscr[000] = newscr[002] =
- newscr[160] = newscr[162] =
- newscr[320] = newscr[322] =
- newscr[480] = newscr[482] = ~((text&0x0F)|((text&0x0f)<<4)) ;
- newscr[640] = newscr[642] =
- newscr[800] = newscr[802] =
- newscr[960] = newscr[962] =
- newscr[1120]= newscr[1122] = ~((text&0xF0)|((text&0xF0)>>4)) ;
- break ;
-
- case 2 :
- newscr += baddr2[scry] + scrx + 1220 ;
- newscr[0] = newscr[80] = newscr[160] = newscr[240] =
- ~((text&0x0F)|((text&0x0f)<<4)) ;
- newscr[320] = newscr[400] = newscr[480] = newscr[560] =
- ~((text&0xF0)|((text&0xF0)>>4)) ;
-
- }
- }
-
- HiPlot (byt,loc) /* hi-res poking */
- register int byt, loc ;
- {
- register int scrx, scry ;
- register char *tempscr ;
- int bitmsk ;
-
- if (videomode&GRAPHICS) /* if we are in graphics mode */
- {
- loc &= 8191 ; /* convert to relative offset from start of screen */
- scry = ( ((((loc&0x7F)/40)<<3)+((loc&0x3FF)>>7) )<<3)
- + (loc>>10) ; /* calculate screen row */
-
- scrx = (loc&0x7F)%40 ; /* screen column */
-
- bitmsk = (scrx&1) + (byt&0x80) ;
-
- /* quickly reverse the order of the bits in byt */
- asm {
- CLR.W D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- ROXR.B #1,byt
- ROXL.B #1,D0
- MOVE.B D0,byt
- }
-
- if (!((videomode&SPLITSCR)&&(scry>159))) {
-
- switch (mode) {
-
- case 2 :
- scr_emul[scry*80+scrx+1220] = ~byt ;
- break ;
- case 0 :
- tempscr = &scr_emul[scry*160 + (scrx&1) + ((scrx&~1)<<2)] ;
- tempscr[6] = (bitmsk&0x80) ? byt : 0 ;
- tempscr[4] = byt&0x2A ;
- tempscr[2] = byt&0x55 ;
- tempscr[0] = (bitmsk&1) ? byt : 0 ;
- break ;
- case 1 :
- tempscr = &scr_emul[scry*160 + (scrx&1) + ((scrx&~1)<<1) + 40] ;
- tempscr[0] = tempscr[2] = ~byt ;
- break ;
- }
- return (1) ;
- }
- }
- return(0) ;
- }
-
-
-